package com.fingard.net;

import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.generalobj.ExecResponse;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.jcraft.jsch.*;

import com.fingard.FGBiz;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.security.Security;
import java.util.*;

public class SftpPortClient {
    private FtpSet ftpSet;
    private ChannelSftp sftpClient;
    private FtpReceiver connReceiver;
    private boolean isExecutedConnect;
    private Session sshSession;

    /**
     * 目录分割符
     */
    private final String SEPARATOR = "/";

    public SftpPortClient(FtpSet p_ftpSet) {
        ftpSet = p_ftpSet;
        connReceiver = new FtpReceiver();
        sftpClient = new ChannelSftp();
        isExecutedConnect = false;
    }

    public void connect() throws IOException {
        isExecutedConnect = true;
        ChannelSftp sftp = null;
        try {
            JSch jsch = new JSch();
            sshSession = jsch.getSession(ftpSet.userName, ftpSet.serverIP, ftpSet.port);
            sshSession.setPassword(ftpSet.userPassword);
            if(StringHelper.hasAnyChar(ftpSet.sshKeyPath)){
            	jsch.addIdentity(ftpSet.sshKeyPath);
            }
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
            Class<ChannelSftp> cl = ChannelSftp.class;
            Field f = cl.getDeclaredField("server_version");
            f.setAccessible(true);
            f.set(sftp, 2);
            this.sftpClient = sftp;
            sftpClient.setFilenameEncoding(ftpSet.charset);
        } catch (Exception ex) {
            FGBiz.limitMsg.exception("SftpPortClient", ex);
            connReceiver.connState = ConnState.FAIL;
            connReceiver.connMsg = LogHelper.getStackTrace(ex);
            disconnect();
        }
    }

    public void connectBySSH() throws IOException {
        isExecutedConnect = true;
        try {
            System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
            JSch.setConfig("StrictHostKeyChecking", "no");
            JSch jsch = new JSch();
            sshSession = jsch.getSession(ftpSet.userName, ftpSet.serverIP, ftpSet.port);
            sshSession.setTimeout(ftpSet.timeout);
            String sshKeyPath = ftpSet.sshKeyPath;
            jsch.addIdentity(sshKeyPath);
            sshSession.connect();
            ChannelSftp channelSftp = (ChannelSftp) sshSession.openChannel("sftp");
            channelSftp.connect();
            this.sftpClient = channelSftp;
            sftpClient.setFilenameEncoding(ftpSet.charset);
        } catch (Exception ex) {
            FGBiz.limitMsg.exception("SftpPortClient", ex);
            connReceiver.connState = ConnState.FAIL;
            connReceiver.connMsg = LogHelper.getStackTrace(ex);
            disconnect();
        }
    }

    /**
     * 连接sftp服务器：需验证私钥密码
     *
     * @param passphrase
     * @throws IOException
     */
    public void connectBySSHPrvkey(String passphrase) throws IOException {
        isExecutedConnect = true;
        try {
            //因对方openSSH版本提供的加密算法jdk1.7版本不支持，引入BouncyCastle包中的加密算法
            //Security.addProvider(new BouncyCastleProvider());//在java.security中security.provider的后面增加一条
            Security.insertProviderAt(new BouncyCastleProvider(), 1);//在java.security中security.provider的1位置增加一条。

            JSch.setConfig("StrictHostKeyChecking", "no");
            JSch jsch = new JSch();
            sshSession = jsch.getSession(ftpSet.userName, ftpSet.serverIP, ftpSet.port);
            sshSession.setTimeout(ftpSet.timeout);
            String sshKeyPath = ftpSet.sshKeyPath;
            jsch.addIdentity(sshKeyPath, passphrase);//私钥，私钥验证密码
            sshSession.connect();
            ChannelSftp channelSftp = (ChannelSftp) sshSession.openChannel("sftp");
            channelSftp.connect();
            this.sftpClient = channelSftp;
            //sftpClient.setFilenameEncoding(ftpSet.charset);
        } catch (Exception ex) {
            ex.printStackTrace();
            connReceiver.connState = ConnState.FAIL;
            connReceiver.connMsg = LogHelper.getStackTrace(ex);
            disconnect();
        }
    }

    /**
     * 连接sftp服务器：需登录密码和验证私钥密码
     *
     * @param passphrase
     * @throws IOException
     */
    public void connectBySSHPrvkeyAndPsd(String passphrase) throws IOException {
        isExecutedConnect = true;
        try {
            //因对方openSSH版本提供的加密算法jdk1.7版本不支持，引入BouncyCastle包中的加密算法
            //Security.addProvider(new BouncyCastleProvider());//在java.security中security.provider的后面增加一条
            Security.insertProviderAt(new BouncyCastleProvider(), 1);//在java.security中security.provider的1位置增加一条。

            JSch.setConfig("StrictHostKeyChecking", "no");
            JSch jsch = new JSch();
            sshSession = jsch.getSession(ftpSet.userName, ftpSet.serverIP, ftpSet.port);
            sshSession.setPassword(ftpSet.userPassword);
            sshSession.setTimeout(ftpSet.timeout);
            String sshKeyPath = ftpSet.sshKeyPath;
            jsch.addIdentity(sshKeyPath, passphrase);//私钥，私钥验证密码
            sshSession.connect();
            ChannelSftp channelSftp = (ChannelSftp) sshSession.openChannel("sftp");
            channelSftp.connect();
            this.sftpClient = channelSftp;
            //sftpClient.setFilenameEncoding(ftpSet.charset);
        } catch (Exception ex) {
            ex.printStackTrace();
            connReceiver.connState = ConnState.FAIL;
            connReceiver.connMsg = LogHelper.getStackTrace(ex);
            disconnect();
        }
    }

    public void disconnect() throws IOException {
        try {
            if (sshSession != null) {
                sshSession.disconnect();
            }
            if (sftpClient != null) {
                sftpClient.disconnect();
            }
        } catch (Exception ex) {
            FGBiz.limitMsg.exception("SftpPortClient." + ftpSet.serverIP, ex);
        }
    }

    public boolean changeWorkingDirectory(String fileDir) throws IOException {
        try {
            if (fileDir.trim().length() > 0) {
                sftpClient.cd(fileDir);
            } else {
                return false;
            }
            return true;
        } catch (SftpException e) {
            FGBiz.limitMsg.exception("SftpPortClient." + ftpSet.serverIP, e);
            return false;
        }
    }

    public boolean isDirExist(String directory) {
        boolean isDirExistFlag = false;
        try {
            SftpATTRS sftpATTRS = this.sftpClient.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        } catch (Exception e) {
            //FGBiz.limitMsg.exception("SftpPortClient."+ftpSet.serverIP, e);
            if (e.getMessage().toLowerCase().equals("no such file")) {
                isDirExistFlag = false;
            }
        }
        return isDirExistFlag;
    }

    public void createDir(String createpath, ChannelSftp sftp) throws SftpException, Exception {
        try {
            if (isDirExist(createpath)) {
                sftp.cd(createpath);
            }
            String pathArry[] = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString())) {
                    sftp.cd(filePath.toString());
                } else {
                    sftp.mkdir(filePath.toString());
                    sftp.cd(filePath.toString());
                }
            }
            this.sftpClient.cd(createpath);
        } catch (SftpException e) {
            throw (e);
        }
    }

    /**
     * 创建目录（先判断目录是否已存在，如不存在则创建）
     */
    public ExecResponse makeDirIfNotExist(String remotePath) throws SftpException, Exception {
        ExecResponse resp = new ExecResponse();
        remotePath = StringHelper.trimEnd(remotePath, SEPARATOR);
        if (StringHelper.isNullOrEmpty(remotePath)) {
            resp.isSucceed = false;
            resp.logMsg = "目录为空";
            return resp;
        }
        if (isDirExist(remotePath)) {
            resp.isSucceed = true;
            return resp;
        } else {
            String pathArry[] = remotePath.split("/");
            StringBuilder filePath = new StringBuilder();
            if (remotePath.startsWith("/")) {
                filePath.append("/");
            }
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString())) {
                    sftpClient.cd(filePath.toString());
                } else {
                    sftpClient.mkdir(filePath.toString());
                    sftpClient.cd(filePath.toString());
                }
            }
            resp.isSucceed = true;
            return resp;
        }
    }

    public FtpReceiver uploadFile(String directDir, String p_localFile, String p_trgFileName) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        FileInputStream in = null;
        try {
            createDir(ftpSet.upDir + directDir, this.sftpClient);
            boolean change = changeWorkingDirectory(ftpSet.upDir + directDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + ftpSet.upDir + directDir + "不存在";
                return retReceiver;
            }
            in = new FileInputStream(p_localFile);
            sftpClient.put(in, p_trgFileName);
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            FGBiz.limitMsg.exception("SftpPortClient", ex);
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;
    }

    /**
     * 上传本地文件到指定目录，如果目录不存在则先创建目录
     */
    public FtpReceiver uploadFileToDir(String p_localFile, String pUpDir, String p_trgFileName) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        FileInputStream in = null;
        try {
            makeDirIfNotExist(pUpDir);
            boolean change = changeWorkingDirectory(pUpDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + pUpDir + "不存在";
                return retReceiver;
            }
            in = new FileInputStream(p_localFile);
            sftpClient.put(in, p_trgFileName);
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;
    }

    /**
     * 上传文件至sftp，防重复推送
     *
     * @param directDir     sftp上传目录下新增文件目录
     * @param p_localFile   本地文件目录
     * @param p_trgFileName 上传sftp文件目录
     * @return 0 上传成功 1 重复上传 2上传失败
     * @throws IOException
     */
    public int uploadFileStatus(String directDir, String p_localFile, String p_trgFileName) throws IOException {
        int result = -1;
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return result;
        }
        FileInputStream in = null;
        try {
            createDir(ftpSet.upDir + directDir, this.sftpClient);
            boolean change = changeWorkingDirectory(ftpSet.upDir + directDir);
            if (!change) {
                return result;
            }
            //判断文件是否存在sftp服务器，不存在上传，存在不上传
            if (sftpClient.ls(p_trgFileName) == null) {
                in = new FileInputStream(p_localFile);
                sftpClient.put(in, p_trgFileName);
                result = 0;
            } else {
                result = 1;
            }
        } catch (Exception ex) {
            FGBiz.limitMsg.exception("SftpPortClient." + ftpSet.serverIP, ex);
            result = -1;
        }
        return result;
    }

    public boolean existFile(String pFileName) throws SftpException {
        if (sftpClient.ls(pFileName) == null) {
            return false;
        } else {
            return true;
        }
    }

    public FtpReceiver deleteFile(String directDir, String target) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        //FileInputStream in = null;
        try {
            if (!isDirExist(directDir)) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "待删除的目录" + directDir + "不存在";
                return retReceiver;
            }
            boolean change = changeWorkingDirectory(directDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + ftpSet.upDir + directDir + "不存在";
                return retReceiver;
            }

            sftpClient.rm(target);
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;
    }


    public FtpReceiver uploadFile(String directDir, InputStream in, String p_trgFileName) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        try {
            createDir(ftpSet.upDir + directDir, this.sftpClient);
            boolean change = changeWorkingDirectory(ftpSet.upDir + directDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + ftpSet.upDir + directDir + "不存在";
                return retReceiver;
            }
            sftpClient.put(in, p_trgFileName);
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;

    }

    public FtpReceiver downloadFile(String directDir, String p_downFileName, String p_saveLocalFile) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        try {
            String targetDir = "";
            if (ftpSet.downDir.endsWith("/")) {
                targetDir = ftpSet.downDir;
            } else {
                targetDir = ftpSet.downDir + "/";
            }
            boolean change = changeWorkingDirectory(targetDir + directDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + ftpSet.downDir + directDir + "不存在";
                return retReceiver;
            }
            try {
                sftpClient.get(p_downFileName, p_saveLocalFile);
            } catch (Exception ex) {
                retReceiver.connState = ConnState.FILE_NOT_EXISTS;
                retReceiver.connMsg = "文件" + p_downFileName + "不存在";
                return retReceiver;
            }
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;
    }

    /**
     * 下载sftp指定的目录（ssh连接）,下载完成之后删除文件
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFile(String targetDir, String saveDir) throws IOException {
        return downloadFile(targetDir, saveDir, false);
    }

    /**
     * 下载sftp指定的目录（ssh连接）
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFile(String targetDir, String saveDir, boolean isDelete) throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if (!isExecutedConnect) {
                connectBySSH();
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean chang = changeWorkingDirectory(ftpSet.downDir + targetDir);
            if (!chang) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "指定目录：" + ftpSet.downDir + targetDir + " 不存在";
                return retReceiver;
            }
            Vector<ChannelSftp.LsEntry> vector = sftpClient.ls(ftpSet.downDir + targetDir);
            for (ChannelSftp.LsEntry lsEntry : vector) {
                String name = lsEntry.getFilename();
                if (!".".equals(name) && !"..".equals(name)) {
                    DownInfoMonitor downInfoMonitor = new DownInfoMonitor();
                    sftpClient.get(name, saveDir, downInfoMonitor);
                    if (downInfoMonitor.isDown) {//判断是否下载成功
                        if (isDelete) {
                            try {
                                sftpClient.rm(StringHelper.trimEndFileSp(ftpSet.downDir + targetDir) + SEPARATOR + name);
                            } catch (Exception ex) {
                                retReceiver.connMsg += "删除" + name + "文件失败";
                            }
                        }
                        fileAppend.append(name + "|");
                        retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(), "|");
                        retReceiver.isCompleted = true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }


    /**
     * 下载sftp指定的目录（ssh连接）
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFileByName(String targetDir, String saveDir, String fileName) throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if (!isExecutedConnect) {
                connectBySSH();
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean chang = changeWorkingDirectory(ftpSet.downDir + targetDir);
            if (!chang) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "指定目录：" + ftpSet.downDir + targetDir + " 不存在";
                return retReceiver;
            }
            sftpClient.get(fileName, saveDir);
            fileAppend.append(fileName + "|");
            retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(), "|");
            retReceiver.isCompleted = true;
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }

    /**
     * 从指定目录下载文件
     */
    public FtpReceiver downloadFileFromDir(String pDownDir, String pDownFileName, String pSaveLocalFile) throws IOException {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            return connReceiver;
        }
        FtpReceiver retReceiver = new FtpReceiver();
        try {
            boolean change = changeWorkingDirectory(pDownDir);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + pDownDir + "不存在";
                return retReceiver;
            }
            File destFile = new File(pSaveLocalFile);
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }
            sftpClient.get(pDownFileName, pSaveLocalFile);
            retReceiver.isCompleted = true;
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }
        return retReceiver;
    }

    /**
     * 下载sftp指定的目录（ssh连接）需要私钥密码验证
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver connectBySSHPrvkeyAndPsd(String targetDir, String saveDir, String passphrase) throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if (!isExecutedConnect) {
                connectBySSHPrvkeyAndPsd(passphrase);
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean chang = changeWorkingDirectory(ftpSet.downDir + targetDir);
            if (!chang) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "指定目录：" + ftpSet.downDir + targetDir + " 不存在";
                return retReceiver;
            }
            Vector<ChannelSftp.LsEntry> vector = sftpClient.ls(ftpSet.downDir + targetDir);
            for (ChannelSftp.LsEntry lsEntry : vector) {
                String name = lsEntry.getFilename();
                sftpClient.get(name, saveDir);
                fileAppend.append(name + "|");
            }
            retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(), "|");
            retReceiver.isCompleted = true;
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }

    /**
     * 下载sftp指定的目录（ssh连接）需要登录密码和私钥密码验证
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFilePrvkey(String targetDir, String saveDir, String passphrase) throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if (!isExecutedConnect) {
                connectBySSHPrvkey(passphrase);
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean chang = changeWorkingDirectory(ftpSet.downDir + targetDir);
            if (!chang) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "指定目录：" + ftpSet.downDir + targetDir + " 不存在";
                return retReceiver;
            }
            Vector<ChannelSftp.LsEntry> vector = sftpClient.ls(ftpSet.downDir + targetDir);
            for (ChannelSftp.LsEntry lsEntry : vector) {
                String name = lsEntry.getFilename();
                sftpClient.get(name, saveDir);
                fileAppend.append(name + "|");
            }
            retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(), "|");
            retReceiver.isCompleted = true;
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }

    /**
     * 下载sftp指定的目录（ssh连接）
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFileBySftp(String targetDir, String saveDir, int type, String password) throws IOException {
        return downloadFileBySftp(targetDir, saveDir, type, password, -1);
    }

    /**
     * 下载sftp指定的目录（ssh连接）三井住友使用
     *
     * @param targetDir sftp目录,
     * @param saveDir   保存文件的目录
     * @return
     */
    public FtpReceiver downloadFileBySftp(String targetDir, String saveDir, int type, String password, int downloadDays) throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if (!isExecutedConnect) {
                switch (type) {
                    case 1:
                        connect();
                        break;
                    case 2:
                        connectBySSH();
                        break;
                    case 3:
                        if (StringHelper.hasAnyChar(password)) {
                            connectBySSHPrvkey(password);
                        } else {
                            throw new Exception("ssh秘钥认证密码未配置，请配置");
                        }
                        break;
                    case 4:
                        if (StringHelper.hasAnyChar(password)) {
                            connectBySSHPrvkeyAndPsd(password);
                        } else {
                            throw new Exception("ssh秘钥认证密码未配置，请配置");
                        }
                        break;
                    default:
                        throw new Exception("类型" + type + "暂不支持，请联系开发人员");
                }
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            String[] downDirList = ftpSet.downDir.split("@");
            for (String downDir : downDirList) {
                String ftpDownDir = StringHelper.trimEndFileSp(downDir) + SEPARATOR + targetDir;
                boolean chang = changeWorkingDirectory(ftpDownDir);
                if (!chang) {
                    retReceiver.connState = ConnState.FAIL;
                    retReceiver.connMsg = "指定目录：" + ftpSet.downDir + targetDir + " 不存在";
                    return retReceiver;
                }
                Vector<ChannelSftp.LsEntry> vector = sftpClient.ls(ftpDownDir);
                for (ChannelSftp.LsEntry lsEntry : vector) {
                    String name = lsEntry.getFilename();
                    if (!".".equals(name) && !"..".equals(name)) {
                        if (downloadDays > -1) {//三井住友特殊处理逻辑，不可复用
                            //获取需要下载前downloadDays天的日期
                            Calendar oneDate = Calendar.getInstance();
                            oneDate.setTime(new Date());
                            oneDate.add(Calendar.DATE, -downloadDays);
                            Date downDate = Format.Date8Format.parse(Format.Date8Format.format(oneDate.getTime()));
                            //根据文件命名规则获取文件生成日期
                            String[] nameArr = name.split("_");
                            Date utilDate = null;
                            if (nameArr.length > 6) {
                                utilDate = Format.Date8Format.parse("20" + nameArr[5]);
                            } else if (nameArr.length > 3) {
                                utilDate = Format.Date8Format.parse("20" + nameArr[0].substring(nameArr[0].length() - 6));
                            }
                            //满足下载日期开始下载文件
                            if (utilDate != null && !utilDate.before(downDate)) {
                                sftpClient.get(name, saveDir);
                                fileAppend.append(name + "|");
                            }
                        } else {
                            sftpClient.get(name, saveDir);
                            fileAppend.append(name + "|");
                        }
                    }
                }
                retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(), "|");
                retReceiver.isCompleted = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState = ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }

    /**
     * 1、下载sftp目录中的文件（ssh连接）
     * 2、过滤已下载到本地的文件
     * @param targetDir sftp下载目录
     * @param saveDir 本地保存目录
     * @return
     * @throws IOException
     */
    public FtpReceiver downloadFileBySftp(String targetDir, String saveDir,String[] fileType)throws IOException {
        FtpReceiver retReceiver = new FtpReceiver();
        StringBuilder fileAppend = new StringBuilder();
        try {
            if(!isExecutedConnect){
                connect();
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            String ftpDownDir=StringHelper.trimEndFileSp(ftpSet.downDir)+SEPARATOR+targetDir;
            boolean chang = changeWorkingDirectory(ftpDownDir);
            if(!chang){
                retReceiver.connState =ConnState.FAIL;
                retReceiver.connMsg ="指定目录："+ftpSet.downDir+targetDir+" 不存在";
                return retReceiver;
            }
            Vector<ChannelSftp.LsEntry> vector = sftpClient.ls(ftpDownDir);
            for(ChannelSftp.LsEntry lsEntry:vector){
                String name = lsEntry.getFilename();
                if(!".".equals(name) && !"..".equals(name)){
                    if(!FileHelper.existFile(StringHelper.trimEndFileSp(saveDir)+SEPARATOR+name)){
                        for(int i=0;i<fileType.length;i++){
                            if(name.contains(fileType[i])){
                                sftpClient.get(name,saveDir);
                                fileAppend.append(name+"|");
                            }
                        }
                    }
                }
            }
            retReceiver.connMsg = StringHelper.trimEnd(fileAppend.toString(),"|");
            retReceiver.isCompleted = true;
        } catch (Exception e) {
            e.printStackTrace();
            retReceiver.connState =ConnState.FAIL;
            retReceiver.connMsg = LogHelper.getStackTrace(e);
            return retReceiver;
        }
        return retReceiver;
    }

    public FtpReceiver listFiles(String directory) throws Exception {
        FtpReceiver retReceiver = new FtpReceiver();

        try {
            if (!isExecutedConnect) {
                connect();
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean change = changeWorkingDirectory(directory);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + directory + "不存在";
                return retReceiver;
            }

            Vector<?> fileList = sftpClient.ls(directory);
            if (fileList.size() <= 2) {
                retReceiver.isCompleted = false;
                retReceiver.connState = ConnState.FILE_NOT_EXISTS;
                retReceiver.connMsg = "SFTP目录暂时生成文件";
                return retReceiver;
            }

            StringBuilder fileNameBuilder = new StringBuilder();
            Iterator<?> it = fileList.iterator();
            while (it.hasNext()) {
                String fileName = ((ChannelSftp.LsEntry) it.next()).getFilename();
                if ((".".equals(fileName)) || ("..".equals(fileName))) {
                    continue;
                }
                fileNameBuilder.append(fileName).append(",");
            }

            retReceiver.isCompleted = true;
            retReceiver.connMsg = fileNameBuilder.toString();
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }

        return retReceiver;
    }

    public FtpReceiver listFiles(String directory, int length) throws Exception {
        FtpReceiver retReceiver = new FtpReceiver();

        try {
            if (!isExecutedConnect) {
                connect();
            }
            if (connReceiver.connState.length() > 0) {
                return connReceiver;
            }
            boolean change = changeWorkingDirectory(directory);
            if (!change) {
                retReceiver.connState = ConnState.FAIL;
                retReceiver.connMsg = "目录" + directory + "不存在";
                return retReceiver;
            }

            Vector<?> fileList = sftpClient.ls(directory);
            if (fileList.size() <= length) {
                retReceiver.isCompleted = false;
                retReceiver.connState = ConnState.FILE_NOT_EXISTS;
                retReceiver.connMsg = "SFTP目录暂无生成文件";
                return retReceiver;
            }

            StringBuilder fileNameBuilder = new StringBuilder();
            Iterator<?> it = fileList.iterator();
            while (it.hasNext()) {
                String fileName = ((ChannelSftp.LsEntry) it.next()).getFilename();
                if ((".".equals(fileName)) || ("..".equals(fileName))) {
                    continue;
                }
                fileNameBuilder.append(fileName).append(",");
            }

            retReceiver.isCompleted = true;
            retReceiver.connMsg = fileNameBuilder.toString();
        } catch (Exception ex) {
            retReceiver.connMsg = LogHelper.getStackTrace(ex);
        }

        return retReceiver;
    }

    /**
     * 取得目录下的所有文件名或子目录名
     */
    public ArrayList<String> listNames(String directory) throws Exception {
        if (!isExecutedConnect) {
            connect();
        }
        if (connReceiver.connState.length() > 0) {
            throw new Exception(connReceiver.connState + "-" + connReceiver.connMsg);
        }
        boolean change = changeWorkingDirectory(directory);
        if (!change) {
            throw new Exception("目录" + directory + "不存在");
        }
        ArrayList<String> retNames = new ArrayList<String>();
        Vector<?> fileList = sftpClient.ls(directory);
        Iterator<?> it = fileList.iterator();
        while (it.hasNext()) {
            String fileName = ((ChannelSftp.LsEntry) it.next()).getFilename();
            if ((".".equals(fileName)) || ("..".equals(fileName))) {
                continue;
            }
            retNames.add(fileName);
        }
        return retNames;
    }
}

/**
 * 内部类,判断下载文件是否成功
 */
class DownInfoMonitor implements SftpProgressMonitor {
    public boolean isDown = false;

    @Override
    public void init(int op, String src, String dest, long max) {

    }

    @Override
    public boolean count(long count) {
        return false;
    }

    @Override
    public void end() {
        isDown = true;
    }
}
